/*
 * system.h
 *
 * Funcoes de gerenciamento do sistema operacioal
 *
 *  Created on: 08/09/2010
 *      Author: wendell
 */

#ifndef __SYSTEM_H
#define __SYSTEM_H

#define NULL 0
#define FALSE 0
#define TRUE 1

#define CMOS_GET_SEC   0x0
#define CMOS_GET_MIN   0x2
#define CMOS_GET_HOUR  0x4
#define CMOS_GET_DAY   0x7
#define CMOS_GET_MONTH 0x8
#define CMOS_GET_YEAR  0x9

#define BCD2BIN(bcd) ((((bcd)&15) + ((bcd)>>4)*10))

#define sti() __asm__ __volatile__("sti")
#define cli() __asm__ __volatile__("cli")

typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef enum{ false=0, true=1 } bool;

extern bool DEGUG;

// Define qual pilha estamos olhando depois de um ISR estar rodando
struct regs
{
    uint gs, fs, es, ds;   //últimos segmentos puxados
    uint edi, esi, ebp, esp, ebx, edx, ecx, eax;  //puxado por 'pusha'
    uint int_no, err_code;   //nosso 'push byte #' e ecodes (códigos de erro) faz isto
    uint eip, cs, eflags, useresp, ss; //puxados pelo processador automaticamente
};

typedef struct regs registers_t;

// Data do sistema
typedef struct{
	int sec;
	int min;
	int hour;
	int day;
	int month;
	int year;
}datetime_t;

/**
 *  Define uma entrada no GDT.
 *  Nós declaramos packed (empacotado), porque isto previne o
 *  compilador de realizar uma compilação "otimizada" por empacotamento
 */
struct GDTEntry {
    ushort limitLow;  // The lower 16 bits of the limit.
    ushort baseLow;   // The lower 16 bits of the base.
    uchar baseMiddle; // The next 8 bits of the base.
    uchar access;     // Access flags, determine what ring this segment can be used in.
    uchar granularity;
    uchar baseHigh;   // The last 8 bits of the base.
} __attribute__((packed));

void t();

/**
 * Ponteiro especial que inclui o limite: O máximo de bytes
 * tomados pela GDT, menos 1.
 * Outra vez, este PRECISA ser packed (empacotado)
 */
struct GDTptr {
    ushort limit;  // The upper 16 bits of all selector limits.
    uint base;      // The address of the first gdt_entry_t struct.
} __attribute__((packed));

// A struct describing a Task State Segment.
struct tss_entry_struct
{
   uint prev_tss;   // The previous TSS - if we used hardware task switching this would form a linked list.
   uint esp0;       // The stack pointer to load when we change to kernel mode.
   uint ss0;        // The stack segment to load when we change to kernel mode.
   uint esp1;       // Unused...
   uint ss1;
   uint esp2;
   uint ss2;
   uint cr3;
   uint eip;
   uint eflags;
   uint eax;
   uint ecx;
   uint edx;
   uint ebx;
   uint esp;
   uint ebp;
   uint esi;
   uint edi;
   uint es;         // The value to load into ES when we change to kernel mode.
   uint cs;         // The value to load into CS when we change to kernel mode.
   uint ss;         // The value to load into SS when we change to kernel mode.
   uint ds;         // The value to load into DS when we change to kernel mode.
   uint fs;         // The value to load into FS when we change to kernel mode.
   uint gs;         // The value to load into GS when we change to kernel mode.
   uint ldt;        // Unused...
   ushort trap;
   ushort iomap_base;
} __attribute__((packed));

typedef struct tss_entry_struct tss_entry_t;


//system/debug.c
void debug(char[]);
void onDebug();
void offDebug();

// system/gdt.c
void gdtSetGate(int, ulong, ulong, uchar, uchar);
void gdtInstall(void);
void write_tss(int num, ushort ss0, uint esp0);

// system/idt.c
void idtSetGate(uchar, ulong, ushort, uchar);
void idtInstall(void);

// system/isrs.c
void isrsInstall(void);

// system/irq.c
void irqInstallHandler(int, void (*handler)(struct regs *r));
void irqUninstallHandler(int);
void irqInstall(void);

// system/timer.c
void timerInstall(void);
void printTime(void);
void printDate(void);

#endif
